//
// Created by LvenLiu on 2022/8/16.
//

#ifndef FFMPEGDEMO_BASECHANNEL_H
#define FFMPEGDEMO_BASECHANNEL_H

extern "C" {
#include <libavcodec/avcodec.h>
}

#include "SafeQueue.h"
#include "AndroidLog.h"

/**
 * 音视频解码公共类
 */
class BaseChannel {
protected:
    int stream_index;// 音视频 下标
    bool playing;
    SafeQueue<AVPacket *> packets; // 压缩的 数据包
    SafeQueue<AVFrame *> frames; // 解压后的 原始数据包
    AVCodecContext *codecContext = nullptr; // 音视频 解码上下文
    // AVPacket 解压的线程
    pthread_t pid_packet_decode;
    // AVFrame 播放的线程
    pthread_t pid_frame_play;

public:
    BaseChannel(int stream_index, AVCodecContext *codecContext) {
        this->stream_index = stream_index;
        this->codecContext = codecContext;

        // 设置包回收
        packets.setReleaseCallback(releaseAVPacket);
        frames.setReleaseCallback(releaseAVFrame);
    }

    ~BaseChannel() {
        LOGE("~BaseChannel");
        if (codecContext) {
            avcodec_free_context(&codecContext);
            codecContext = nullptr;
        }
    }

    // 开始
    virtual void start() = 0;

    // 停止
    virtual void stop() = 0;

    // packet解压线程方法
    virtual void packet_decode() = 0;

    // frame线程播放方法
    virtual void frame_play() = 0;

    int streamIndex() {
        return stream_index;
    }

    void addAVPacket(AVPacket *packet) {
        packets.offer(packet);
    }

    void addAVFrame(AVFrame *frame) {
        frames.offer(frame);
    }

    /**
     * 回收压缩包
     */
    static void releaseAVPacket(AVPacket **p) {
        if (p) {
            av_packet_free(p);
            *p = nullptr;
        }
    }

    /**
     * 回收 解压后的原始数据包
     */
    static void releaseAVFrame(AVFrame **f) {
        if (f) {
            av_frame_free(f);
            *f = nullptr;
        }
    }
};

#endif //FFMPEGDEMO_BASECHANNEL_H
